<html>
<head>
<title>Remake de Fruity Frank - Version 0.01</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.SpanClass0 {
	color: #808080;
}
.SpanClass3 {
	color: #008080;
}
.SpanClass5 {
	font-weight: bold;
	color: #0000FF;
}
.SpanClass7 {
	color: #808080;
}
.SpanClass10 {
	font-weight: bold;
	color: #000080;
}
.SpanClass11 {
}
</style>
</head>
<body bgcolor="#FFFFFF">
<h2>Remake (parcial) de Fruity Frank... 01 - Mostrar el fondo </h2>
<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
<p>En este primer acercamiento vamos a preparar las herramientas que usaremos para crear el juego, y las probaremos para mostrar la imagen de fondo del juego. </p>
<ul>
  <li>Como entorno de desarrollo usaremos <a href="http://www.codeblocks.org/">CodeBlocks</a>, que incluye el compilador GNU de C y C++, junto con entorno integrado (editor y depurador). Se podr&iacute;a usar cualquier otro, pero en el apartado de &quot;Descargas&quot; dejar&eacute; un proyecto de CodeBlocks listo para ser usado simplemente con un &quot;doble clic&quot; desde Windows. Quien elija usar otro entorno de desarrollo tendr&aacute; que hacer un poco m&aacute;s de &quot;trabajo manual&quot;.</li>
  <li>Como biblioteca que nos proporcione las funcionalidades b&aacute;sicas usaremos <a href="http://www.libsdl.org/">SDL</a> (Simple DirectMedia Layer) </li>
  <li>Nos apoyaremos en un par de ficheros auxiliares que se encargan de ocultar los detalles de SDL y de permitirnos usar &oacute;rdenes traducidas al espa&ntilde;ol, algo m&aacute;s sencillas.&nbsp; Todas estas &oacute;rdenes comenzar&aacute;n por &quot;SDLA_&quot;, para distinguirlas de las &oacute;rdenes &quot;normales&quot; de C++ y/o de SDL. </li>
</ul>
<p>Usando estos ficheros auxiliares, un primer fuente de prueba ser&iacute;a as&iacute;:</p>

<pre><code>#include &quot;SDL_ASI.h&quot;

int main (int argc, char** argv)
{
    SDLA_inicializar(640,480,24);

    SDLA_Imagen* fondoPantalla;
    fondoPantalla=SDLA_cargarImagen(&quot;fondo.bmp&quot;);

    SDLA_dibujarImagenOculta(fondoPantalla,0,0);
    SDLA_visualizarOculta();

    SDLA_esperarTecla();
    return 0;
}</code></pre>
<p>Vamos a ver l&iacute;nea por l&iacute;nea lo que hace, porque entenderlo ser&aacute; vital para poder irlo ampliando...</p>
<ul>
  <li>#include &quot;SDL_ASI.h&quot; - Carga uno de los ficheros auxiliares que necesitamos, el fichero de cabecera &quot;SDL_ASI.h&quot;.</li>
  <li>int main (int argc, char** argv) - Comienzo del cuerpo del programa (&quot;main&quot;). </li>
  <li> SDLA_inicializar(640,480,24);
- Inicializa la pantalla gr&aacute;fica, escogiendo el modo de 640 x 480 puntos (ancho x alto) y 24 bits de color (16 millones de colores).</li>
  <li>SDLA_Imagen* fondoPantalla; - Declara una variable llamada &quot;fondoPantalla&quot;, que ser&aacute; una imagen (tipo SDLA_Imagen*)</li>
  <li>fondoPantalla=SDLA_cargarImagen(&quot;fondo.bmp&quot;);
 - Prepara el valor de &quot;fondoPantalla&quot;: ser&aacute; una imagen que se cargue de disco, llamada &quot;fondo.bmp&quot;.</li>
  <li>SDLA_dibujarImagenOculta(fondoPantalla,0,0); - Dibuja la imagen &quot;fondoPantalla&quot; en las coordenadas (0,0) de la pantalla oculta, es decir en la esquina superior izquierda. Para evitar parpadeos en pantalla, siempre dibujaremos los elementos de nuestro juego uno a uno en una pantalla oculta, y finalmente haremos que toda esa pantalla oculta pase a ser visible.</li>
  <li>SDLA_visualizarOculta();
 - Hace que la pantalla oculta se pueda ver.</li>
  <li>SDLA_esperarTecla(); - Esperamos a que se pulse una tecla.</li>
  <li> return 0; - Termina el cuerpo del programa. <br>
  </li>
</ul>
<p>Para probar todo esto, bastar&iacute;a con descargar el entorno CodeBlocks, a&ntilde;adirle los paquetes de SDL (al menos SDL y SDL_ttf) desde el men&uacute; hacer doble clic en el fichero del proyecto: &quot;fruity.cbp&quot;. S&oacute;lo hace falta que hayamos preparado una imagen de fondo del juego, que se llame &quot;fondo.bmp&quot;, que podr&iacute;amos haber capturado del juego original, usando un emulador (esta imagen forma parte del proyecto que se puede descargar).</p>
<p>Para poner en marcha el &quot;supuesto juego&quot; (que todav&iacute;a es poco jugable), entrar&iacute;amos al men&uacute; &quot;Build&quot; (construir) de CodeBlocks y escoger&iacute;amos la opci&oacute;n &quot;Build &amp; Run&quot; (construir y ejecutar). Si todo es correcto (deber&iacute;a ser as&iacute;), deber&iacute;a aparecer la pantalla de fondo del juego y esperar que pulsemos una tecla, momento en el que se acaba &quot;el juego&quot;. </p>
<hr>
<p>Para los que tengan m&aacute;s conocimientos t&eacute;cnicos, voy a dar alg&uacute;n detalle m&aacute;s de c&oacute;mo son los otros dos ficheros auxiliares que forman parte de nuestro proyecto. </p>
<p>El primero de ellos, el que incluimos desde nuestro juego, se llama SDL_ASI.h, y es un fichero de cabecera que tiene los res&uacute;menes de las posibilidades de nuestra &quot;mini-biblioteca&quot; SDL_ASI, junto con las declaraciones de constantes:</p>
<pre><code>#ifndef SDL_ASI_H

#define SDL_ASI_H

#include &lt;SDL/SDL.h&gt;
#include &lt;SDL/SDL_ttf.h&gt;

/* Adaptacion de SDL, ocultando lo basico y
   traduciendo al castellano */

/* =====================================
 Versiones anteriores:

Numero    Fecha    Cambios
------- ---------- ----------------

 0.04   18/05/2007 Permite escribir texto en la pantalla oculta
                     (necesita SDL_TTF)
                   A&ntilde;adida una funcion para vaciar buffer de
                     teclado

 0.03   18/05/2007 A&ntilde;adido &quot;esperaTecla&quot;, para poder esperar a
                     que se pulse una tecla sin necesidad de &quot;while&quot;.
                   A&ntilde;adidas varias constantes m&aacute;s para teclas habituales:
                     n&uacute;meros del 0 al 5, espacio.

 0.02   27/04/2007 A&ntilde;adido &quot;colision&quot;, corregido &quot;teclaPulsada&quot;,
                     que usaba parametro &quot;char&quot; en vez de &quot;int&quot;,
                     separados prototipos (.h) de codigo (.c)

 0.01   26/04/2007 Versi&oacute;n inicial, que enmascara SDL: permite
                     inicializar, borrar la pantalla oculta,
                     cargar una imagen, dibujar una imagen en la
                     pantalla oculta, visualizar la pantalla
                     oculta, ver si se ha pulsado el rat&oacute;n, ver
                     si se ha pulsado una tecla, y define las teclas
                     del cursor y ESC.


===================================== */

#define SDLA_Imagen SDL_Surface
#define SDLA_Fuente TTF_Font
#define SDLA_Color  SDL_Color

#define TECLA_ESC SDLK_ESCAPE
#define TECLA_DER SDLK_RIGHT
#define TECLA_ARR SDLK_UP
#define TECLA_ABA SDLK_DOWN
#define TECLA_IZQ SDLK_LEFT

#define TECLA_J SDLK_j
#define TECLA_A SDLK_a
#define TECLA_C SDLK_c
#define TECLA_R SDLK_r
#define TECLA_V SDLK_v
#define TECLA_1 SDLK_1
#define TECLA_2 SDLK_2
#define TECLA_3 SDLK_3
#define TECLA_4 SDLK_4

#define TECLA_ESP SDLK_SPACE

/*---------------------------*/


int SDLA_inicializar(int ancho, int alto, int colores);

SDLA_Imagen* SDLA_cargarImagen(char *fichero);

void SDLA_colorTransparente(SDLA_Imagen* imagen,
      int r, int g, int b);

int SDLA_borrarPantallaOculta(int r, int g, int b);

int  SDLA_dibujarImagenOculta(SDLA_Imagen *imagen,
      int x,int y);

int  SDLA_escribirTextoOculta(char *frase,
      int x,int y, int color, SDLA_Fuente *fuente);

int SDLA_visualizarOculta();

int SDLA_teclaPulsada(int c);

int SDLA_esperarTecla();

void SDLA_vaciarBufferTeclado();

int SDLA_ratonPulsado(int *x, int *y);

int SDLA_pausa(long milisegundos);

int SDLA_colision(int x1, int y1, int an1, int al1,
      int x2, int y2, int an2, int al2);

#endif</code>
</pre>
<p>&nbsp; </p>
<p>El segundo fichero, que no incluimos directamente desde "juego.cpp", pero es parte del proyecto, se llama &quot;sdlasi.c&quot;, y contiene los detalles de esas funciones:</p>
<pre><code>#include &quot;SDL_ASI.h&quot;


/* Adaptacion de SDL, ocultando lo basico y
   traduciendo al castellano */

SDLA_Fuente *SDLA_arial12;
SDLA_Fuente *SDLA_arial24;

SDLA_Imagen* pantallaOculta;
SDLA_Imagen* pantallaVisible;


int SDLA_inicializar(int ancho, int alto, int colores) {
    // Inicializo SDL
    if ( SDL_Init( SDL_INIT_VIDEO ) &lt; 0 )
        exit(1);

    // Me aseguro de que SDL limpia al salir
    atexit(SDL_Quit);

    // Creo la pantalla visibl
    pantallaVisible = SDL_SetVideoMode(
      ancho, alto, colores,
      SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !pantallaVisible )
        exit(2);

    // Y la oculta
    pantallaOculta = SDL_CreateRGBSurface(SDL_SWSURFACE,
      ancho,alto,colores, 0,0,0,0);
    if ( !pantallaOculta )
        exit(3);

    // Inicializo SDL_TTF
    if ( TTF_Init() &lt; 0 )
        exit(5);
    atexit(TTF_Quit);

    SDLA_arial12 = TTF_OpenFont(&quot;arial.ttf&quot;,12);
    SDLA_arial24 = TTF_OpenFont(&quot;arial.ttf&quot;,24);

    return 0;
}

SDLA_Imagen* SDLA_cargarImagen(char *fichero) {
    SDLA_Imagen* imagen;
    imagen = SDL_LoadBMP(fichero);
    if (imagen == NULL)
      exit(4);
    return imagen;
}


void SDLA_colorTransparente(SDLA_Imagen* imagen,
      int r, int g, int b){

    SDL_SetColorKey(imagen,
      SDL_SRCCOLORKEY|SDL_RLEACCEL,
      SDL_MapRGB(imagen-&gt;format, r,g,b));
}

int SDLA_borrarPantallaOculta(int r, int g, int b) {
    SDL_FillRect(pantallaOculta,
      0,SDL_MapRGB(pantallaOculta-&gt;format,
      r,g,b));
}

int  SDLA_dibujarImagenOculta(SDLA_Imagen *imagen,
      int x,int y){

    SDL_Rect posicion;
    posicion.x = x;
    posicion.y = y;
    SDL_BlitSurface(imagen, 0,
      pantallaOculta, &amp;posicion);
}

int  SDLA_escribirTextoOculta(char *frase,
      int x,int y, int color, SDLA_Fuente *fuente){

    SDLA_Color bgcolor,fgcolor;
    SDLA_Imagen *textoComoImagen;

    /* El color de primer plano sera el escogido */
    fgcolor.r = (color &amp; 0xff0000)&gt;&gt;16;
    fgcolor.g = (color &amp; 0x00ff00)&gt;&gt;8;
    fgcolor.b = color &amp; 0x0000ff;

    /* El fondo sera negro (transparente) */
    bgcolor.r=0;
    bgcolor.g=0;
    bgcolor.b=0;

    /* Preparo el bitmap */
    textoComoImagen = TTF_RenderText_Shaded(fuente,
      frase,fgcolor,bgcolor);
    SDLA_colorTransparente(textoComoImagen,0,0,0);

    /* Y dibujo */
    SDLA_dibujarImagenOculta(textoComoImagen, x,y);
}

int SDLA_visualizarOculta() {
    SDL_BlitSurface(pantallaOculta, 0,
      pantallaVisible, 0);
    SDL_Flip( pantallaVisible );
}

int SDLA_teclaPulsada(int c) {
    SDL_PumpEvents();
    Uint8 *keys = SDL_GetKeyState(NULL);
    if (keys[c] == 1)
      return 1;
    else
      return 0;
}

int SDLA_esperarTecla() {
    SDL_Event suceso;

   /* Imitacion de &quot;getch()&quot; para SDL */
   while (1) {                            /* Repetimos indefinidamente */
     while (SDL_PollEvent(&amp;suceso)) {     /* Comprobamos sucesos */
         if (suceso.type == SDL_KEYDOWN)  /* Si es tecla pulsada */
           return suceso.key.keysym.sym;  /* La devolvermos */
       }
   }

}

void SDLA_vaciarBufferTeclado() {
    SDL_Event suceso;

     while ((SDL_PollEvent(&amp;suceso)) &amp;&amp;
          (suceso.type == SDL_KEYDOWN))
    ;
}


int SDLA_ratonPulsado(int *x, int *y) {
    SDL_PumpEvents();

    return(SDL_GetMouseState(x,y)&amp;SDL_BUTTON(1));
}

int SDLA_pausa(long milisegundos) {
    SDL_Delay(milisegundos);
}

int SDLA_colision(int x1, int y1, int an1, int al1,
      int x2, int y2, int an2, int al2) {
    if ((x2+an2 &gt; x1)
        &amp;&amp; (y2+al2 &gt; y1)
        &amp;&amp; (x1+an1 &gt; x2)
        &amp;&amp; (y1+al1 &gt; y2))
      return 1;
    else
      return 0;
}</code></pre>
<p>&nbsp;</p>
<p>Siendo estrictos, necesitamos dos cosas m&aacute;s (que tambi&eacute;n se pueden descargar desde la p&aacute;gina del proyecto): las DLL llamadas SDL.DLL y SDL_TTF.DLL, que deber&iacute;an estar accesibles (al menos en el PATH, pero para distribuir nuestro juego puede ser c&oacute;modo que se encuentren en la misma carpeta que el ejecutable) y el tipo de letra ARIAL.TTF (en las msimas condiciones).
</p>
<p>&iquest;Y cual es la p&aacute;gina del proyecto? <a href="http://code.google.com/p/fruityfrank"> code.google.com/p/fruityfrank</a></p>
<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
